package com.leectrl.adapter;

import android.content.SharedPreferences;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hdl.school.application.MyApplication;
import com.hdl.school.entity.NormalSerialCode;
import com.leectrl.bean.ZigbeeDevice;
import com.leectrl.utils.Bus;
import com.leectrl.utils.DbUtil;
import com.leectrl.utils.HexUtil;

import org.xutils.ex.DbException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;


public class TCPServerHandler extends ChannelInboundHandlerAdapter {
    private String aiBoxIP = null;
    private int checkDur = 30;
    private Map<String, Long> noBodyInfo = new HashMap<>();
    private Map<String, Map<String, String[]>> lightMap = new HashMap<>();

    public TCPServerHandler() {
        JSONArray lineConfig = null;
        SharedPreferences sharedPreferences = MyApplication.myApplication.getSharedPreferences("school_iot", 0);
        String aiConfigStr = sharedPreferences.getString("c_setting_aiConfig", null);
        if (aiConfigStr != null) {
            JSONObject aiConfig = JSON.parseObject(aiConfigStr);
            lineConfig = aiConfig.getJSONArray("config");
            aiBoxIP = aiConfig.getString("boxIp");
            if(aiConfig.containsKey("nobodyDur")){
                checkDur=aiConfig.getIntValue("nobodyDur");
            }

        }
        Map<String, String[]> lineMap = new HashMap<>();
        try {
            List<ZigbeeDevice> zigbeeDevices = DbUtil.getInstance().selector(ZigbeeDevice.class).findAll();
            if (zigbeeDevices != null) {
                for (ZigbeeDevice zigbeeDevice : zigbeeDevices) {
                    if (zigbeeDevice.getDeviceType().indexOf("switcher") > 0) {
                        String[] keys = zigbeeDevice.getDevicekey().split(",");
                        for (int m = 0; m < keys.length; m++) {
                            lineMap.put(keys[m], new String[]{zigbeeDevice.getMac(), String.valueOf(m)});
                        }
                    }
                }
            }
            for (int j = 0; j < lineConfig.size(); j++) {
                JSONArray line = lineConfig.getJSONObject(j).getJSONArray("line");
                if (line != null && line.size() > 0) {
                    Map<String, String[]> devInfo = new HashMap<>();
                    for (int k = 0; k < line.size(); k++) {
                        String lineKey=line.getString(k);
                        if(lineMap.containsKey(lineKey)) {
                            devInfo.put(lineKey, lineMap.get(lineKey));
                        }
                    }
                    String areaNum = Integer.toHexString(j + 1);
                    if (areaNum.length() < 2) {
                        areaNum = "0" + areaNum;
                    }
                    lightMap.put(areaNum, devInfo);
                }

            }
        } catch (DbException e) {
            e.printStackTrace();
        }

    }

    //收到数据时调用
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            ByteBuf in = (ByteBuf) msg;
            int readableBytes = in.readableBytes();
            byte[] bytes = new byte[readableBytes];
            in.getBytes(in.readerIndex(), bytes);
            handleTCPMessage(HexUtil.bytes2HexString(bytes));
        } finally {

        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
        ctx.flush();
    }

    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 当出现异常就关闭连接
        cause.printStackTrace();
        ctx.close();
    }

    /*
     * 建立连接时，返回消息
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        String clientInfo = String.valueOf(ctx.channel().remoteAddress());
        String clientIP = null;
        if (clientInfo != null && clientInfo.indexOf("/") == 0 && clientInfo.indexOf(".") > 0 && clientInfo.indexOf(":") > 0) {
            clientIP = clientInfo.substring(1, clientInfo.indexOf(":"));
        }
        if (clientIP == null || aiBoxIP == null || (!aiBoxIP.equals(clientIP))) {
            ctx.close();
            return;
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        String clientInfo = String.valueOf(ctx.channel().remoteAddress());
        String clientIP = null;
        if (clientInfo != null && clientInfo.indexOf("/") == 0 && clientInfo.indexOf(".") > 0 && clientInfo.indexOf(":") > 0) {
            clientIP = clientInfo.substring(1, clientInfo.indexOf(":"));
        }
        if (clientIP == null || aiBoxIP == null || (!aiBoxIP.equals(clientIP))) {
            return;
        }
    }


    private void handleTCPMessage(String hex) {
        String hexStr = hex.toLowerCase();
        Log.e("ccc",hexStr);
        if (hexStr.startsWith("fafb") && hexStr.length() > 50) {
            int len = Integer.parseInt(hexStr.substring(4, 6), 16);
            if (hexStr.length() == (len + 2) * 2) {
                String noBodyHex = hexStr.substring(hexStr.length() - (len - 25) * 2, hexStr.length() - 2);
                Log.e("TCP", noBodyHex);
                long now = System.currentTimeMillis();
                for (int i = 0; i < noBodyHex.length() / 4; i++) {
                    String areaNum = noBodyHex.substring(4 * i, 4 * i + 2);
                    int bodyNum = Integer.parseInt(noBodyHex.substring(4 * i + 2, 4 * i + 4), 16);
                    Log.e("ccc",areaNum+"区"+bodyNum+"人");
                    if (bodyNum == 0) {
                        long lastHasBodyTime = 0;
                        if (noBodyInfo.containsKey(areaNum)) {
                            lastHasBodyTime = noBodyInfo.get(areaNum);
                        }
                        if (now - lastHasBodyTime > checkDur*1000) {
                            noBodyInfo.put(areaNum, now+checkDur*1000);
                            //执行关灯
                            Log.e("ccc",areaNum+"区关灯");
                            if(lightMap.containsKey(areaNum)){
                                Map<String,String[]> devInfo=lightMap.get(areaNum);
                                Iterator iterator=devInfo.entrySet().iterator();
                                while (iterator.hasNext()){
                                    Map.Entry<String,String[]> key= (Map.Entry<String, String[]>) iterator.next();
                                    String[] info=devInfo.get(key.getKey());
                                    NormalSerialCode normalSerialCode = new NormalSerialCode();
                                    List<String> codes = new ArrayList<>();
                                    codes.add("c"+(Integer.parseInt(info[1])+1)+"2b");
                                    codes.add("02");
                                    codes.add("00");
                                    normalSerialCode.setCode(codes);
                                    Bus.getInstance().emit("zigbee_code",info[0],normalSerialCode);
                                }
                            }

                        }
                    } else {
                        noBodyInfo.put(areaNum, now);
                    }
                }
            }
        }
    }
}
